/**
 * @fileOverview Cube Javascript Framework Core - Cube.js
 * @author <a href="mailto:simonsliu@tencent.com">simonsliu</a>
 * @date 11-11-16 - 上午11:38
 */
(function() {
	var global = this;

	/**
	 * @name Cube
	 * @class Cube
	 */
	global.Cube = global.Cube || function( selector, context ) {
		return new Cube.Element( selector, context );
	};

	Cube.global = global;

	Cube.enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable',
                       'toLocaleString', 'toString', 'constructor'];

	/**
	 * 对象合并方法，引用自jQuery.extend
	 * @memberOf Cube
	 */
	Cube.merge = function() {
		var options, name, src, copy, copyIsArray, clone,
			target = arguments[0] || {},
			i = 1,
			length = arguments.length,
			deep = false;

		// Handle a deep copy situation
		if ( typeof target === "boolean" ) {
			deep = target;
			target = arguments[1] || {};
			// skip the boolean and the target
			i = 2;
		}

		// Handle case when target is a string or something (possible in deep copy)
		if ( typeof target !== "object" && !Cube.isFunction(target) ) {
			target = {};
		}

		// extend Cube itself if only one argument is passed
		if ( length === i ) {
			target = this;
			--i;
		}

		for ( ; i < length; i++ ) {
			// Only deal with non-null/undefined values
			if ( (options = arguments[ i ]) != null ) {
				// Extend the base object
				for ( name in options ) {
					src = target[ name ];
					copy = options[ name ];

					// Prevent never-ending loop
					if ( target === copy ) {
						continue;
					}

					// Recurse if we're merging plain objects or arrays
					if ( deep && copy && ( Cube.isPlainObject(copy) || (copyIsArray = Cube.isArray(copy)) ) ) {
						if ( copyIsArray ) {
							copyIsArray = false;
							clone = src && Cube.isArray(src) ? src : [];

						} else {
							clone = src && Cube.isPlainObject(src) ? src : {};
						}

						// Never move original objects, clone them
						target[ name ] = Cube.merge( deep, clone, copy );

					// Don't bring in undefined values
					} else if ( copy !== undefined ) {
						target[ name ] = copy;
					}
				}
			}
		}

		// Return the modified object
		return target;
	};
	/**
	 * @lends Cube
	 */
	Cube.merge({
		/**
		 * Create an alias to the provided method property with name `methodName` of `object`.
		 * Note that the execution scope will still be bound to the provided `object` itself.
		 * @memberOf Cube
		 * @param {Object/Function} object
		 * @param {String} methodName
		 * @return {Function} aliasFn
		 */
		alias: function(object, methodName) {
			return function() {
				return object[methodName].apply(object, arguments);
			};
		}
	});


	(function() {
		// 类型判断辅助
		var class2type = {},
			toString = Object.prototype.toString,
			hasOwn = Object.prototype.hasOwnProperty,
			enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable',
                       'toLocaleString', 'toString', 'constructor'];
		
		"Boolean Number String Function Array Date RegExp Object".split(" ").forEach(function( name, i ) {
			class2type["[object " + name +"]"] = name.toLowerCase();
		});
		/**
		 * 类型检查静态方法集，引用自jQuery
		 * @lends Cube
		 */
		Cube.merge({
			/**
			 * 判断类型
			 * @param {Object} value 判断目标
			 * @return {String} 类型字符串
			 */
			type: function( value ) {
				return value === null ?
					String( value ) :
					class2type[ toString.call( value ) ] || "object";
			},
			/**
			 * 传入参数为一个Javascript数组时，返回true，否则返回false
			 * @function
			 * @param {Array} value 判断目标
			 * @return {Boolean}
			 */
			isArray: ( 'isArray' in Array ) ? /** @ignore */Array.isArray : function( value ) {
				return Cube.type( value ) === "array";
			},
			/**
			 * 传入参数为一个Javascript函数时，返回true，否则返回false
			 * @param {Function} value 判断目标
			 * @return {Boolean}
			 */
			isFunction: function( value ) {
				return Cube.type( value ) === "function";
			},
			/**
			 * 传入参数为一个Javascript空白对象(json格式)时，返回true，否则返回false
			 * @param {Object} value 判断目标
			 * @return {Boolean}
			 */
			isPlainObject: function( value ) {
				// Must be an Object.
				// Because of IE, we also have to check the presence of the constructor property.
				// Make sure that DOM nodes and window objects don't pass through, as well
				if ( !value || Cube.type(value) !== "object" || value.nodeType || Cube.isWindow( value ) ) {
					return false;
				}

				// Not own constructor property must be Object
				if ( value.constructor &&
					!hasOwn.call(value, "constructor") &&
					!hasOwn.call(value.constructor.prototype, "isPrototypeOf") ) {
					return false;
				}

				// Own properties are enumerated firstly, so to speed up,
				// if last one is own, then all properties are own.

				var key;
				for ( key in value ) {}

				return key === undefined || hasOwn.call( value, key );
			},
			/**
			 * 传入参数为一个Javascript空对象({})时，返回true，否则返回false
			 * @param {Object} value 判断目标
			 * @return {Boolean}
			 */
			isEmptyObject: function( value ) {
				for ( var name in value ) {
					return false;
				}
				return true;
			},
			/**
			 * 传入参数为一个Javascript字符串时，返回true，否则返回false
			 * @param {String} value 判断目标
			 * @return {Boolean}
			 */
			isString: function( value ) {
				return Cube.type( value ) === "string";
			},
			/**
			 * 传入参数为一个Javascript数字时，返回true，否则返回false
			 * @param {Function} value 判断目标
			 * @return {Boolean}
			 */
			isNumber: function( value ) {
				return Cube.type( value ) === "number";
			},
			/**
			 * 传入参数为Javascript Boolean类型时，返回true，否则返回false
			 * @param {Boolean} value 判断目标
			 * @return {Boolean}
			 */
			isBoolean: function( value ) {
				return Cube.type( value ) === "boolean";
			},
			/**
			 * 传入参数为Javascript 正则表达式类型时，返回true，否则返回false
			 * @param {Boolean} value 判断目标
			 * @return {Boolean}
			 */
			isRegExp: function( value ) {
				return Cube.type( value ) === "regexp";
			},
			/**
			 * 传入参数为Javascript 日期类型时，返回true，否则返回false
			 * @param {Boolean} value 判断目标
			 * @return {Boolean}
			 */
			isDate: function( value ) {
				return Cube.type( value ) === "date";
			},
 			/**
			 * 传入参数为一个window对象时，返回true，否则返回false
			 * @param {DOMWindow} value 判断目标
			 * @return {Boolean}
			 */
			isWindow: function( value ) {
				return value && typeof value === "object" && "setInterval" in value;
			},
			/**
			 * Clone almost any type of variable including array, object, DOM nodes and Date without keeping the old reference
			 * @param {Object} item The variable to clone
			 * @return {Object} clone
			 */
			clone: function(item) {
				if (item === null || item === undefined) {
					return item;
				}

				// DOM nodes
				// TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
				// recursively
				if (item.nodeType && item.cloneNode) {
					return item.cloneNode(true);
				}

				var type = toString.call(item);

				// Date
				if (type === '[object Date]') {
					return new Date(item.getTime());
				}

				var i, j, k, clone, key;

				// Array
				if (type === '[object Array]') {
					i = item.length;

					clone = [];

					while (i--) {
						clone[i] = Cube.clone(item[i]);
					}
				}
				// Object
				else if (type === '[object Object]' && item.constructor === Object) {
					clone = {};

					for (key in item) {
						clone[key] = Cube.clone(item[key]);
					}

					if (enumerables) {
						for (j = enumerables.length; j--;) {
							k = enumerables[j];
							clone[k] = item[k];
						}
					}
				}

				return clone || item;
			},
			// args is for internal usage only
			each: function( object, callback, args ) {
				var name, i = 0,
					length = object.length,
					isObj = length === undefined || Cube.isFunction( object );

				if ( args ) {
					if ( isObj ) {
						for ( name in object ) {
							if ( callback.apply( object[ name ], args ) === false ) {
								break;
							}
						}
					} else {
						for ( ; i < length; ) {
							if ( callback.apply( object[ i++ ], args ) === false ) {
								break;
							}
						}
					}

				// A special, fast, case for the most common use of each
				} else {
					if ( isObj ) {
						for ( name in object ) {
							if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
								break;
							}
						}
					} else {
						for ( ; i < length; ) {
							if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
								break;
							}
						}
					}
				}

				return object;
			},
			/**
			 * 空函数
			 * @field
			 * @type Function
			 */
			noop: function(){},
			/**
			 * 全局唯一id
			 * @type Number
			 */
			guid: 1
		});
	})();
})();
// ui包命名空间，just for documentation
/**
 * @name Cube.ui
 * @namespace
 */
/**
 * @name Cube.ui.button
 * @namespace
 */
/**
 * @name Cube.ui.container
 * @namespace
 */
/**
 * @name Cube.ui.dialog
 * @namespace
 */
/**
 * @name Cube.ui.tip
 * @namespace
 */